<script setup lang="ts">
defineOptions({
  name: "fabBoardEchartsModelBoxItem"
});

import { ref, nextTick, defineAsyncComponent, getCurrentInstance, useSlots, inject, computed } from "vue";
import { Download, Document } from "@px-ui/icons-vue";
import fabBoardModelBoxItem from "./fabBoardModelBoxItem.vue";
import modelBox from "@/views/common/components/modelBox/index.vue";
import { useInitPieEcharts, useInitBarEcharts, useInitLineEcharts } from "./fabBoardSpcModelBoxItemEchartsHooks";
import fabBoardEchartsModelBoxItemDialog from "./fabBoardEchartsModelBoxItemDialog.vue";
import dayjs from "dayjs";
import { promiseTimeout } from "@vueuse/core";

const emitBoardEventCb = inject("emitBoardEvent") as Function;
const emitBoardPieAreaEventCb = inject("emitBoardPieAreaEvent") as Function;

const { proxy }: any = getCurrentInstance();
const slots = useSlots();

const echartsCom = defineAsyncComponent(() => import("@/views/common/components/echartsCom/index.vue"));

const echartsComRef = ref<InstanceType<typeof echartsCom> | null>(null);

const props = withDefaults(
  defineProps<{
    echartsType?: "line" | "line-water" | "pie" | "bar";
    data?: Record<string, any> | Array<Record<string, any>> | null;
    title?: string;
    dialogTitle?: string;
    name?: string;
    unit?: string;
    exportImage?: boolean;
    exportData?: boolean;
    materialCode?: string;
    areaCode?: string;
    eventType?: string; //  eqpStatus 机台状态统计   areaCode 机台区域用量统计
  }>(),
  {
    echartsType: "line",
    data: null,
    title: "",
    dialogTitle: "",
    name: "",
    unit: "",
    exportImage: false,
    exportData: false,
    eventType: ""
  }
);

const loading = defineModel("loading", { type: Boolean, default: false });

const spcType = ref<"all" | "up" | "down" | "">("all");
const dialogType = ref<number>(0); //  0 所有机台当天24小时用量统计  1 每个机台当天总用量统计
const dialogVisible = ref<boolean>(false);
const date = ref<string>("");
const oneDayTitle = ref<string>("");
const oneDayAreaCode = ref<string>("");

const barDataIndexArr = ref<Array<number>>([]);

const realAreaCode = computed(() => {
  switch (props.eventType) {
    case "eqpStatus":
      return props.areaCode;
    case "areaCode":
      return oneDayAreaCode.value;
    default:
      return props.areaCode;
  }
});

const spcTypeOption = ref<Array<any>>([
  {
    label: "双边",
    value: "all",
    disabled: false
  },
  {
    label: "上单边",
    value: "up",
    disabled: false
  },
  {
    label: "下单边",
    value: "down",
    disabled: false
  }
]);

const echartsOptions = ref<CommonEcharts.CommonEchartsOption | null>(null);

const emits = defineEmits<{
  (e: "exportImageChange"): void;
  (e: "exportDataChange"): void;
}>();

// 表头具体点位指标名称
// const title = computed(() => `${props.data?.indicatorName || ""}${props.data?.pointUnit ? "（" + props.data?.pointUnit + "）" : ""}`);

/**
 * @description:  配置echarts  饼图/环形图
 * @param {*} flag  是否首次加载
 * @param {*} flag2  是否环形图   true 环形图    false 饼图
 * @return {*}
 */
const initPieEcharts = async (flag: boolean = false, flag2: boolean = false) => {
  if (!props.data?.length) {
    echartsOptions.value = null;
    await nextTick();
    !flag && (await echartsComRef.value?.updateOption(flag));
    return;
  }
  const title = flag2 ? props.name || props.title : props.title || props.name;
  await promiseTimeout(0);
  await useInitPieEcharts(echartsComRef.value, flag2, title, props.data as Array<Record<string, any>>, props.unit, options => {
    echartsOptions.value = options;
  });
  await nextTick();
  !flag && (await echartsComRef.value?.updateOption(flag));
  setTimeout(async () => {
    const ec = await echartsComRef.value?.getEcharts();
    ec?.getInstance()?.off("click");
    ec?.getInstance()?.on("click", params => {
      switch (props.eventType) {
        case "eqpStatus":
        case "pmTask":
        case "repairTask":
        case "abnormalAlarm":
          emitBoardEventCb(props.eventType, params.data);
          break;
        case "areaCode":
          dialogType.value = 1;
          oneDayAreaCode.value = params.data.areaCode;
          oneDayTitle.value = `${props.dialogTitle} 区域（${params.data.areaCode}） 日期（${dayjs().format("YYYY/MM/DD")}）`;
          dialogVisible.value = true;
          break;
        case "areaCodePie":
          emitBoardPieAreaEventCb(props.eventType, params.data);
          break;
      }
    });
  }, 0);
};

/**
 * @description: 配置echarts  柱状图
 * @param {*} flag  是否首次加载
 * @param {*} flag2  是否不需要折线
 * @param {*} flag3  是否不需要当天统计弹框
 * @param {*} cb
 * @return {*}
 */
const initBarEcharts = async (flag: boolean = false, flag2: boolean = false, flag3: boolean = false, cb?: (data?: any, flag?: boolean) => void) => {
  if (!props.data?.length) {
    echartsOptions.value = null;
    await nextTick();
    !flag && (await echartsComRef.value?.updateOption(flag));
    return;
  }
  await promiseTimeout(0);
  useInitBarEcharts(flag2, flag3, props.title, props.data as Array<Record<string, any>>, props.unit, options => {
    echartsOptions.value = options;
  });
  await nextTick();
  !flag && (await echartsComRef.value?.updateOption(flag));
  setTimeout(async () => {
    const ec = await echartsComRef.value?.getEcharts();
    ec?.getInstance()?.off("click");
    ec?.getInstance()?.on("click", params => {
      if (flag3) {
        if (!!barDataIndexArr.value.length) {
          if (barDataIndexArr.value.includes(params.dataIndex)) {
            barDataIndexArr.value.splice(0);
            cb && cb(params, true);
          } else {
            barDataIndexArr.value.splice(0);
            barDataIndexArr.value.push(params.dataIndex);
            cb && cb(params);
          }
        } else {
          barDataIndexArr.value.push(params.dataIndex);
          cb && cb(params);
        }
      } else {
        dialogType.value = 0;
        date.value = params?.data?.dayStr;
        oneDayTitle.value = `${props.title} 日期（${dayjs(params?.data?.dayStr).format("YYYY/MM/DD")}）`;
        dialogVisible.value = true;
      }
    });
  }, 0);
};

const spcTypeChangeHandler = async (val: string, flag: boolean = false) => {
  if (props.echartsType === "line" && !props.data?.pointValues?.length) {
    echartsOptions.value = null;
    await nextTick();
    !flag && (await echartsComRef.value?.updateOption(flag));
    return;
  } else if (props.echartsType === "line-water" && !props.data?.hourValueList?.length) {
    echartsOptions.value = null;
    await nextTick();
    !flag && (await echartsComRef.value?.updateOption(flag));
    return;
  }
  const type = props.echartsType === "line" ? 0 : props.echartsType === "line-water" ? 1 : 0;
  switch (val) {
    case "up":
      useInitLineEcharts(type, ["up"], props.title, props.unit, props.data, data => {
        echartsOptions.value = data;
      });
      break;
    case "down":
      useInitLineEcharts(type, ["down"], props.title, props.unit, props.data, data => {
        echartsOptions.value = data;
      });
      break;
    default:
      useInitLineEcharts(type, ["up", "down"], props.title, props.unit, props.data, data => {
        echartsOptions.value = data;
      });
      break;
  }
  await nextTick();
  !flag && (await echartsComRef.value?.updateOption(flag));
};

const removeEcharts = async () => {
  echartsOptions.value = null;
  await nextTick();
  await echartsComRef.value?.updateOption(true);
};

const init = async (flag: boolean = false, flag2: boolean = false, flag3: boolean = false, cb?: (data?: any, flag?: boolean) => void) => {
  await nextTick();
  loading.value = true;
  spcType.value = "all";
  switch (props.echartsType) {
    case "pie":
      await initPieEcharts(flag, flag2);
      break;
    case "bar":
      await initBarEcharts(flag, flag2, flag3, cb);
      break;
    case "line":
    case "line-water":
      await spcTypeChangeHandler("", flag);
      break;
  }
  loading.value = false;
};

const exportImageHandler = async () => {
  await nextTick();
  const echartsRef = await echartsComRef.value?.getEcharts();
  proxy.useDownloadEcharts(echartsRef);
  emits("exportImageChange");
};

const exportDataHandler = async () => {
  emits("exportDataChange");
};

defineExpose({ barDataIndexArr, loading, init, removeEcharts, el: echartsComRef });
</script>

<template>
  <modelBox :title="title">
    <!-- <template v-if="!!slots?.headLeft" #headLeft>
      <div>
        <slot name="headLeft" />
      </div>
    </template> -->
    <template v-if="!!slots?.title || exportImage || exportData" #title>
      <div class="title-right">
        <px-tooltip v-if="exportImage" :disabled="!echartsOptions" effect="dark" content="导出图片">
          <px-button type="primary" :disabled="!echartsOptions" text :icon="Download" @click="exportImageHandler" />
        </px-tooltip>
        <!-- <span /> -->
        <px-tooltip v-if="exportData" :disabled="!echartsOptions" effect="dark" content="导出数据">
          <px-button type="primary" :disabled="!echartsOptions" text :icon="Document" @click="exportDataHandler" />
        </px-tooltip>
        <slot v-if="!!slots?.headRight" name="headRight" />
      </div>
    </template>
    <div v-loading="loading" class="fab-board-model-box-item">
      <div v-if="echartsType === 'line-water'" class="spc-type">
        <div class="head-center">
          <!-- <px-radio-group v-model="spcType" size="small" @change="spcTypeChangeHandler">
            <px-radio-button v-for="item in spcTypeOption" :key="item.value" :label="item.value">{{ item.label }}</px-radio-button>
          </px-radio-group> -->
        </div>
        <div class="title-slot-right">
          <slot name="titleRight" />
        </div>
      </div>
      <div
        class="spc-echarts"
        :style="{
          height: echartsType === 'line-water' ? 'calc(100% - 24px)' : '100%',
          marginTop: '0'
        }"
      >
        <Suspense>
          <template #fallback>
            <div v-loading="true" class="echarts-fallback" />
          </template>
          <template #default>
            <div class="echarts-content">
              <echartsCom ref="echartsComRef" :options="echartsOptions" />
            </div>
          </template>
        </Suspense>
      </div>
    </div>
  </modelBox>
  <fabBoardEchartsModelBoxItemDialog
    v-if="dialogVisible"
    v-model="dialogVisible"
    :type="dialogType"
    :materialCode="materialCode"
    :areaCode="realAreaCode"
    :date="date"
    :title="oneDayTitle"
    :unit="unit"
  />
</template>

<style lang="scss" scoped>
.title-right {
  display: flex;
  gap: 16px;
  align-items: center;

  .px-button {
    padding: 0;

    & + .px-button {
      margin-left: 0;
    }
  }
}

.fab-board-model-box-item {
  width: 100%;
  height: 100%;

  .spc-type {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    justify-content: flex-end;

    .head-center {
      display: flex;
      justify-content: center;
      width: 100%;
      height: 0;

      .px-radio-group {
        margin: auto;
      }
    }
  }

  .spc-echarts {
    width: 100%;

    .echarts-fallback {
      width: 100%;
      height: 100%;
    }

    .echarts-content {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
